<template>
  <!-- 加载动画 -->
  <div v-if="isLoadingUrl">
    <SvgIcon name="loading-twotone-loop" class="h-5 w-5" :style="{ color: color }" />
  </div>

  <div v-else-if="isPlaying"
    class="wave-container ml-2"
    :class="{ 'is-playing': isPlaying }"
    :style="containerStyle"
  >
    <!-- 音波 -->
    <div
      v-for="(bar, index) in bars"
      :key="index"
      class="wave-bar"
      :style="getBarStyle(bar)"
    ></div>
  </div>

  <div v-else class="flex items-center text-[#9c9ca4] cursor-pointer h-5 hover:text-[#9c9ca4]/80 transition-colors" @click="handleClick">    
    <SvgIcon name="volume" class="h-5 w-5"/>
    <div v-show="url" class="ml-1 text-[13px]">{{ Math.floor(duration) }}s</div>
  </div>
</template>

<script setup>
import { ref, computed, watch, onMounted } from 'vue';
// 导入 Composable
import { useAudio } from '@/composables/useAudio';
import { message } from 'ant-design-vue';

// ----------------------
// 🔊 Props 和 Audio Logic
// ----------------------
const props = defineProps({
  // 1. 基础配置
  url: { type: String, required: true },
  density: { type: Number, default: 1 },   // 密度（每秒几根）

  // 2. 外观尺寸配置
  width: { type: [Number, String], default: 'auto' }, 
  height: { type: [Number, String], default: '20px' }, 

  // 3. 线条配置
  barWidth: { type: Number, default: 1.5 }, // 线条宽度 (px)，越宽圆角越明显
  barGap: { type: Number, default: 2 },   // 线条之间的间距 (px)
  color: { type: String, default: 'rgb(51, 51, 51)' }, // 线条颜色
  // 新增：接收一个异步函数，用于在URL不存在时生成它
  generateUrlFn: { 
      type: Function, 
      default: () => Promise.resolve(null) 
  },
});

// 调用 Composable 获取独立状态和方法
const { duration, isPlaying, togglePlay, setUrl } = useAudio(props.url);

// ----------------------
// 💻 UI 状态和计算属性
// ----------------------
const bars = ref([]);
// 是否正在等待后端生成URL
const isLoadingUrl = ref(false);

// 计算样式：将 props 转换为 CSS 变量
const containerStyle = computed(() => {
  return {
    '--wave-width': typeof props.width === 'number' ? `${props.width}px` : props.width,
    '--wave-height': typeof props.height === 'number' ? `${props.height}px` : props.height,
    '--bar-color': props.color,
    '--bar-width': `${props.barWidth}px`,
    '--bar-gap': `${props.barGap}px`,
  };
});

// 计算音波数量 (基于时长)
const barCount = computed(() => {
  const count = Math.ceil(duration.value * props.density);
  // 确保最少有 5 个波
  // return Math.max(5, count); 
  return 4
});

// 生成随机动画参数，只在时长变化时触发
const generateBars = () => {
  const newBars = [];
  for (let i = 0; i < barCount.value; i++) {
    newBars.push({
      maxHeightScale: 0.4 + Math.random() * 0.6, // 随机高度 (40% ~ 100%)
      animDuration: 0.8 + Math.random() * 0.7,   // 随机时长
      animDelay: Math.random() * -1              // 随机延迟
    });
  }
  bars.value = newBars;
};

// 动态样式绑定
const getBarStyle = (bar) => {
  return {
    '--max-scale': bar.maxHeightScale,
    'animation-duration': `${bar.animDuration}s`,
    'animation-delay': `${bar.animDelay}s`
  };
};

// 监听 duration 变化，重新生成波形数据
watch(duration, (newVal) => {
  if (newVal > 0) {
    generateBars();
  }
}, { immediate: true });

onMounted(() => {
  // 确保在 duration 变化之前，至少有一次生成尝试
  if (duration.value === 0) {
    generateBars();
  }
});

// 统一的点击处理函数
const handleClick = async () => {
  // 场景1：已存在且正在播放/暂停
  if (duration.value > 0 || props.url) {
      // 使用 useAudio 的核心逻辑
      togglePlay();
      return;
  }

  // 场景2：URL 不存在，需要生成
  if (!props.url && !isLoadingUrl.value && props.generateUrlFn) {
    isLoadingUrl.value = true;

    console.log("开始生成音频URL...");

    try {
      // 调用父组件传入的异步生成函数
      const newUrl = await props.generateUrlFn();

      if (newUrl) {
        console.log("生成音频URL成功:", newUrl);
        // 1. 更新 useAudio 内部的 URL
        setUrl(newUrl); 
        // 2. 立即开始播放
        togglePlay();
      }
    } catch (error) {
      console.error("生成音频URL失败:", error);

      message.error("生成音频URL失败");
    } finally {
      isLoadingUrl.value = false;
    }
  }
}
</script>

<style scoped>
.wave-container {
  /* 布局控制 */
  display: inline-flex;
  align-items: center; /* 垂直居中，确保音波向上下两端扩散 */
  justify-content: flex-start; /* 默认靠左，因为有 gap */

  /* 尺寸与外观 */
  width: var(--wave-width);
  height: var(--wave-height);
  gap: var(--bar-gap); /* 使用 gap 控制间距 */

  cursor: pointer;
  overflow: hidden;
  user-select: none;
}

.wave-bar {
  /* 形状控制 */
  width: var(--bar-width);
  /* 使用 999px 确保无论是 2px 宽还是 10px 宽，都是完美的半圆头 */
  border-radius: 999px;
  background-color: var(--bar-color);

  /* 初始状态 */
  height: 10%;

  /* 动画 */
  animation-name: wave-animation;
  animation-timing-function: ease-in-out;
  animation-iteration-count: infinite;
  animation-play-state: paused;
  will-change: height; /* 性能优化 */
}

.wave-container.is-playing .wave-bar {
  animation-play-state: running;
}

@keyframes wave-animation {
  0% {
    height: 10%; /* 最低高度 */
  }
  50% {
    /* 动态计算最高高度：容器高度 * 随机系数 */
    height: calc(100% * var(--max-scale));
  }
  100% {
    height: 10%;
  }
}
</style>
